﻿/**
 * @file   FITKAbsExtendTool.h
 * @brief  抽象类工具类
 * @author YanZhiHui (chanyuantiandao@126.com)
 * @date   2025-05-06
 */
#ifndef FITK_ABS_EXTENT_TOOL
#define FITK_ABS_EXTENT_TOOL

#include "qglobal.h"
#include "FITKAbsVirtualTopoMapper.h"

namespace Interface
{
    /**
     * @brief  ACIS的补充工具类.
     * @author YanZhiHui(chanyuantiandao@126.com)
     * @date   2025-02-26
     */
    class FITKAbsExtendTool {

    public:
        FITKAbsExtendTool() = delete;
        ~FITKAbsExtendTool() = delete;

        /**
         * @brief  计算向量叉积
         * @param  first 第一个向量数组
         * @param  second 第二个向量数组
         * @param  result 结果向量数组
         * @author YanZhiHui (chanyuantiandao@126.com)
         * @data   2025-05-06
         */
        static void crossVector(const double* const first, const double* const second, double*& result) {
            result[0] = first[1] * second[2] - first[2] * second[1];
            result[1] = first[2] * second[0] - first[0] * second[2];
            result[2] = first[0] * second[1] - first[1] * second[0];
        }

        /**
         * @brief  计算向量点积
         * @param  first 第一个向量数组
         * @param  second 第二个向量数组
         * @author YanZhiHui (chanyuantiandao@126.com)
         * @data   2025-05-06
         */
        static double dotVector(const double* const first, const double* const second) {
            return first[0] * second[0] + first[1] * second[1] + first[2] * second[2];
        }

        /**
         * @brief  判断向量是否为零向量
         * @param  vec 要判断的向量
         * @author YanZhiHui (chanyuantiandao@126.com)
         * @data   2025-05-06
         */
        static bool isZeroVector(const double* const vec) {
            return qFuzzyIsNull(vec[0]) && qFuzzyIsNull(vec[1]) && qFuzzyIsNull(vec[2]);
        }

        /**
         * @brief  向量的模
         * @param  vec 向量
         * @author YanZhiHui (chanyuantiandao@126.com)
         * @data   2025-05-06
         */
        static double vectorNorm(const double* const vec) {
            return std::sqrt(std::pow(vec[0], 2) + std::pow(vec[1], 2) + std::pow(vec[2], 2));
        }

        /**
         * @brief  两个向量是否反向
         * @param  first 第一个向量数组
         * @param  second 第二个向量数组
         * @author YanZhiHui (chanyuantiandao@126.com)
         * @data   2025-05-06
         */
        static bool isFlipDirection(const double* const first, const double* const second) {
            if (isZeroVector(first) || isZeroVector(second)) return false;
            auto cosVal = dotVector(first, second) / vectorNorm(first) / vectorNorm(second);
            return qFuzzyCompare(cosVal, -1.0);
        }

        /**
         * @brief  判断边是否在面的拓扑上
         * @param  edge 边
         * @param  Face 面
         * @author YanZhiHui (chanyuantiandao@126.com)
         * @data   2025-05-07
         */
        static bool isEdgeOnFaceTopo(VirtualShape edge, VirtualShape face) {
            FITKVirtualTopoMapper mapper;

            mapper.mapTopo(face.VirtualTopoId, FITKGeoEnum::VTopoShapeType::VSEdge);

            const int nbEdges = mapper.length();

            for (int i = 0; i < nbEdges; ++i) {
                if (mapper.virtualTopo(i)->getDataObjectID() == edge.VirtualTopoId) return true;
            }
            return false;
        }
    };
}


#endif // !FITK_ABS_EXTENT_TOOL
